home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / examples / mrarpfil / part02 < prev   
Encoding:
Internet Message Format  |  1990-06-03  |  19.7 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i175: MRARPFile 1.1 - routines to enhance ARP file-handling, Part02/02
  5. Message-ID: <12701@xanth.cs.odu.edu>
  6. Date: 3 Jun 90 23:30:54 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: mrr@amanpt1.Newport.RI.US (Mark Rinfret)
  9. Lines: 617
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: mrr@amanpt1.Newport.RI.US (Mark Rinfret)
  15. Posting-number: Volume 90, Issue 175
  16. Archive-name: examples/mrarpfile-1.1/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 2)."
  25. # Contents:  MRARPFile.c
  26. # Wrapped by tadguy@xanth on Sun Jun  3 19:29:31 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'MRARPFile.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'MRARPFile.c'\"
  30. else
  31. echo shar: Extracting \"'MRARPFile.c'\" \(17486 characters\)
  32. sed "s/^X//" >'MRARPFile.c' <<'END_OF_FILE'
  33. X/*  File support routines to complement ARP.
  34. X *  Author: Mark R. Rinfret
  35. X *          Usenet:     mrr@amanpt1.Newport.RI.US
  36. X *          BIX:        markr
  37. X *          CIS:        72017, 136 (good luck!)
  38. X *
  39. X *          348 Indian Avenue
  40. X *          Portsmouth, RI 02871
  41. X *          401-846-7639 (home)
  42. X *          401-849-9390 (work)       
  43. X *
  44. X *  This package was written primarily because of _one_ missing element
  45. X *  in ARP: FGets. ARGH! ARPFFFT! It extends ARP by adding buffering to
  46. X *  the basic file type (FileHandle) and defining a new type, named
  47. X *  ARPFileHandle (hope this is OK with the ARP guys). Also, I've used the
  48. X *  convention of embedding ARP (vs. Arp in MicroSmith's stuff) in all type
  49. X *  and function names to (hopefully) avoid naming collisions.
  50. X *
  51. X *  This package (as far as I am concerned) is public domain. Use it any
  52. X *  way you like. Some comments on the "MR" prefix: it isn't short for
  53. X *  "Mister", it comprises the initials of my first and last names.
  54. X *  I use it primarily to avoid name collisions with stuff by other
  55. X *  authors. If any other authors whose initials are "MR" start doing
  56. X *  this, we'll probably have to appeal to Electronic Arts to dole out
  57. X *  "author codes" along the lines of those issued for IFF :-). I hereby
  58. X *  stake a claim to 'MRR_'.
  59. X *
  60. X *  A word of warning:
  61. X *
  62. X *  DO NOT INTERMIX STANDARD AMIGADOS FILE SUPPORT CALLS WITH CALLS TO
  63. X *  THIS PACKAGE ON FILES USING THIS FILE METHOD!
  64. X *
  65. X *  Obviously, the system doesn't know about the buffering added here
  66. X *  and will cause unpredictable results if you mix calls to this package
  67. X *  with calls to Read/Write/Seek, etc. (unless, of course, you take care 
  68. X * to maintain the ARPFileHandle information).
  69. X */
  70. X
  71. X
  72. X#if __STDC__
  73. X#include <stdlib.h>
  74. X#endif
  75. X
  76. X#include "MRARPFile.h"
  77. X#include <exec/memory.h>
  78. X#include <string.h>
  79. X#include <functions.h>
  80. X
  81. X#ifndef min
  82. X#define min(a,b) ((a) <= (b) ? (a) : (b))
  83. X#define max(a,b) ((a) >= (b) ? (a) : (b))
  84. X#endif
  85. X
  86. X/* struct DefaultTracker *StoreTracker __PARMS( (void) ); */
  87. X
  88. Xstatic LONG FillARPFileBuffer __PARMS( (ARPFileHandle *file) );
  89. Xstatic LONG FlushARPFileBuffer __PARMS( (ARPFileHandle *file) );
  90. X
  91. X/*  FUNCTION
  92. X *      FGetsARP - get string from a buffered ARP file.
  93. X *
  94. X *  SYNOPSIS
  95. X *      #include <MRARPFile.h>
  96. X *
  97. X *      char *FGetsARP(s, length, file)
  98. X *                     UBYTE         *s;
  99. X *                     LONG           length;
  100. X *                     ARPFileHandle *file;
  101. X *
  102. X *  DESCRIPTION
  103. X *      FGetsARP models the behavior of the "standard" fgets, except that
  104. X *      it is used with a buffered ARP file. The data is read from <file>
  105. X *      and transfered to string <s>. Up to length-1 characters will be
  106. X *      read. Reading is also terminated upon receipt of a newline
  107. X *      or detection of end-of-file. 
  108. X *
  109. X *      If the <file> was opened without a buffer, one of MaxInputBuf
  110. X *      bytes will be allocated.
  111. X *
  112. X *      If end of file or an error is detected, the return value will be
  113. X *      NULL. Otherwise, the return value will be <s>. <s> will be 
  114. X *      terminated with a null byte.
  115. X */
  116. Xchar *
  117. XFGetsARP(s, length, file)
  118. X    char            *s;
  119. X    LONG            length;
  120. X    ARPFileHandle   *file;
  121. X{
  122. X    LONG    bytesNeeded = length - 1;
  123. X    LONG    bytesRead = 0;
  124. X    char    c;
  125. X    char    *s1 = s;
  126. X
  127. X    /* Set string initially empty to protect user from failure to check
  128. X     * return value.
  129. X     */
  130. X    *s1 = '\0';    
  131. X    if (file->mode != MODE_OLDFILE)
  132. X        file->lastError = ERROR_READ_PROTECTED;
  133. X         
  134. X    if (file->lastError) {
  135. Xdangit:
  136. X        return NULL;
  137. X    }
  138. X    if (! file->buf ) {                 /* Ohmigosh! No buffer? */
  139. X        file->buf = ArpAlloc(MaxInputBuf);
  140. X        if (! file->buf ) {
  141. X            file->lastError = ERROR_NO_FREE_STORE;
  142. X            goto dangit;
  143. X        }
  144. X        file->bufSize = MaxInputBuf;    /* bufLength, bufPos are zero. */
  145. X    }
  146. X    while (bytesNeeded) {
  147. X        if (file->bufPos >= file->bufLength) {
  148. X            if (FillARPFileBuffer(file) < 0) goto dangit;
  149. X            if (file->bufLength == 0) break;
  150. X        }
  151. X        c = file->buf[file->bufPos++];
  152. X        ++bytesRead;
  153. X        if (c == '\n') break;
  154. X        *s1++ = c;
  155. X        --bytesNeeded; 
  156. X    }
  157. X    *s1 = '\0';
  158. X    return (bytesRead ? s : NULL);
  159. X}
  160. X
  161. X/*  FUNCTION
  162. X *      FillARPFileBuffer - read data into ARPFile buffer.
  163. X *
  164. X *  SYNOPSIS
  165. X *      #include <MRARPFile.h>
  166. X *
  167. X *      static LONG FillARPFileBuffer(file)
  168. X *                                    ARPFileHandle *file;
  169. X *
  170. X *  DESCRIPTION
  171. X *      Attempt to fill the buffer associated with <file> by reading
  172. X *      data from the associated external file. The return value will
  173. X *      be one of the following:
  174. X *          >0  => number of bytes read
  175. X *           0  => end of file
  176. X *          -1  => a Bad Thing happened (error code in file->lastError) 
  177. X *
  178. X *      Note: this is a local routine and is thus declared as "static".
  179. X *      Please inform the author if this is a hardship.
  180. X */
  181. Xstatic LONG
  182. XFillARPFileBuffer(file)
  183. X    ARPFileHandle *file;
  184. X{
  185. X    /* Remember where we were. The user might want to try error
  186. X     * recovery. Of course, this probably isn't enough info, but
  187. X     * it's a start.
  188. X     */
  189. X    file->lastPosition = Seek(file->fh, 0L, OFFSET_CURRENT);
  190. X    file->bufPos = 0;
  191. X    file->bufLength = Read(file->fh, file->buf, file->bufSize);
  192. X    if (file->bufLength == -1) {    /* We got trubble! */
  193. X        file->lastError = IoErr();
  194. X    }
  195. X    else if (file->bufLength == 0) {
  196. X        file->endOfFile = TRUE;
  197. X    }
  198. X    return file->bufLength;
  199. X} 
  200. X
  201. X/*  FUNCTION
  202. X *      FlushARPFileBuffer - write file buffer contents to disk.
  203. X *
  204. X *  SYNOPSIS
  205. X *      #include <MRARPFile.h>
  206. X *
  207. X *      static LONG FlushARPFileBuffer(ARPFileHandle *file);
  208. X *
  209. X *  DESCRIPTION
  210. X *      FlushARPFileBuffer writes the contents of <file>'s buffer
  211. X *      (if any) to disk and resets the buffer information. The
  212. X *      return value may be any of:
  213. X *
  214. X *          >0 =>   number of bytes written
  215. X *           0 =>   nothing in buffer
  216. X *          <0 =>   negated error code
  217. X *
  218. X *      Note: it is assumed that this function will only be used locally
  219. X *      and therefore need not be public. If you disagree, please contact
  220. X *      the author.
  221. X */
  222. X
  223. Xstatic LONG
  224. XFlushARPFileBuffer(file)
  225. X    ARPFileHandle *file;
  226. X{
  227. X    LONG    bytesWritten = 0;
  228. X
  229. X    /* This operation is only allowed for output files. */
  230. X
  231. X    if (file->mode != MODE_NEWFILE) {
  232. X        file->lastError = ERROR_WRITE_PROTECTED;
  233. Xbadstuff:
  234. X        return -file->lastError;
  235. X    }
  236. X
  237. X    if (file->lastError) goto badstuff; /* Residual error? */
  238. X
  239. X    if (file->bufLength) {
  240. X        file->lastPosition = Seek(file->fh, 0L, OFFSET_CURRENT);
  241. X        bytesWritten = Write(file->fh, (const char *) file->buf, file->bufLength);
  242. X        if (bytesWritten != file->bufLength) {
  243. X            file->lastError = IoErr();
  244. X            goto badstuff;
  245. X        }
  246. X        else {
  247. X            file->bufLength = 0;
  248. X            file->bufPos = 0;
  249. X        }
  250. X    }
  251. X    return bytesWritten;
  252. X}
  253. X
  254. X/*  FUNCTION
  255. X *      FPutsARP - write a string to a buffered ARP file.
  256. X *
  257. X *  SYNOPSIS
  258. X *      #include <MRARPFile.h>
  259. X *
  260. X *      LONG FPutsARP(s, file)
  261. X *                    char          *s;
  262. X *                    ARPFileHandle *file;
  263. X *
  264. X *  DESCRIPTION
  265. X *      FPutsARP writes the contents of string <s> to the specified <file>.
  266. X *      If successful, it returns 0. On failure, it returns the negated
  267. X *      system error code. 
  268. X */
  269. XLONG
  270. XFPutsARP(s, file)
  271. X    char          *s;
  272. X    ARPFileHandle *file;
  273. X{
  274. X    LONG    bytesLeft, bytesUsed;
  275. X    char    *s1 = s;
  276. X
  277. X    if (file->mode != MODE_NEWFILE) 
  278. X        file->lastError = ERROR_WRITE_PROTECTED;
  279. X
  280. X    if (file->lastError) {
  281. Xshucks:
  282. X        return -file->lastError;
  283. X    }
  284. X
  285. X    bytesLeft = strlen(s);
  286. X
  287. X    /* Attempt to be smart about this transfer. Copy the string to the
  288. X     * buffer in chunks. There is a possibility that the string is bigger
  289. X     * than the size of the buffer.
  290. X     */
  291. X    while (bytesLeft) {
  292. X        if (file->bufPos >= file->bufSize) {
  293. X            if (FlushARPFileBuffer(file) <= 0) goto shucks;
  294. X        }
  295. X        bytesUsed = min(file->bufSize - file->bufPos, bytesLeft);
  296. X        CopyMem(s1, &file->buf[file->bufPos], bytesUsed);
  297. X        s1 += bytesUsed;
  298. X        file->bufLength = (file->bufPos += bytesUsed);
  299. X        bytesLeft -= bytesUsed;
  300. X    }
  301. X    return 0;
  302. X}
  303. X
  304. X/*  FUNCTION
  305. X *      ReadARPFile - read from a buffered ARP file.
  306. X *
  307. X *  SYNOPSIS
  308. X *      #include <MRARPFile.h>
  309. X *
  310. X *      LONG ReadARPFile(ARPFileHandle *file, char *buffer, LONG length);
  311. X *
  312. X *  DESCRIPTION
  313. X *      ReadARPFile attempts to read <length> bytes from <file>, transferring
  314. X *      the data to <buffer>. 
  315. X *
  316. X *      The return value may be any of the following:
  317. X *
  318. X *          >0      number of bytes transferred
  319. X *          0       end of file
  320. X *         <0       negated error code
  321. X *
  322. X *      Note: if the lastError field of the <file> descriptor contains a
  323. X *            non-zero value, its negated value will be returned and no
  324. X *            attempt will be made to read the file. If you attempt error
  325. X *            recovery, you must clear this field to zero.
  326. X */
  327. XLONG
  328. XReadARPFile(file, buffer, length)
  329. X    ARPFileHandle   *file;
  330. X    char            *buffer;
  331. X    LONG            length;
  332. X{
  333. X    LONG            bytesLeft;
  334. X    LONG            bytesRead = 0;
  335. X    LONG            needBytes = length;
  336. X    LONG            pos = 0;
  337. X    LONG            usedBytes = 0;
  338. X
  339. X    /* Prevent read if this file opened for writing. */
  340. X
  341. X    if (file->mode != MODE_OLDFILE)
  342. X        file->lastError = ERROR_READ_PROTECTED;
  343. X
  344. X    if (file->lastError) {          /* Have residual error? */
  345. Xboofar:
  346. X        return -file->lastError;
  347. X    }
  348. X
  349. X    if ( ! file->buf ) {            /* No buffer? */
  350. X        bytesRead = Read(file->fh, buffer, length);
  351. X        if (bytesRead == -1) {
  352. X            file->lastError = IoErr();
  353. X            goto boofar;
  354. X        }
  355. X    }
  356. X    else while (needBytes) {
  357. X        if (file->bufLength - file->bufPos <= 0) {
  358. X            if (FillARPFileBuffer(file) == -1) goto boofar;
  359. X            if (file->bufLength == 0) break;
  360. X        }
  361. X        bytesLeft = file->bufLength - file->bufPos;
  362. X        usedBytes = min(bytesLeft, length);
  363. X        CopyMem(&file->buf[file->bufPos], &buffer[pos], usedBytes);
  364. X        file->bufPos += usedBytes;
  365. X        pos += usedBytes;
  366. X        bytesRead += usedBytes;
  367. X        needBytes -= usedBytes;
  368. X    }
  369. X    return bytesRead;   
  370. X}
  371. X
  372. X/*  FUNCTION
  373. X *      CloseARPFile - close buffered ARP file.
  374. X *
  375. X *  SYNOPSIS
  376. X *      #include <MRARPFile.h>
  377. X *
  378. X *      LONG CloseARPFile(file)
  379. X *                        ARPFileHandle *file;
  380. X *
  381. X *  DESCRIPTION
  382. X *      CloseARPFile closes the file described by <file> which MUST have
  383. X *      been opened by OpenARPFile. It releases all tracked items
  384. X *      associated with <file>, as well.
  385. X *
  386. X *      The return value is only meaningful for output files. If, upon
  387. X *      flushing the buffer, a write error is detected, a system error
  388. X *      code (ERROR_DISK_FULL, etc.) will be returned.
  389. X */
  390. X
  391. XLONG
  392. XCloseARPFile(file)
  393. X    ARPFileHandle *file;
  394. X{
  395. X    LONG        result = 0;
  396. X
  397. X    if (file) {                     /* Just in case... */
  398. X        if (file->fileTracker) {
  399. X            /* Any left-over stuff in the buffer? If so, we must flush
  400. X             * it to disk. However, if an error was detected in the
  401. X             * previous operation, punt. 
  402. X             */
  403. X            if ( ( file->mode == MODE_NEWFILE) && 
  404. X                   ! file->lastError &&
  405. X                   file->bufLength) {
  406. X                if (Write(file->fh, (const char *) file->buf, file->bufLength) !=
  407. X                    file->bufLength)
  408. X                    result = IoErr();
  409. X            }
  410. X            FreeTrackedItem(file->fileTracker);
  411. X        }
  412. X
  413. X        FreeTrackedItem((struct DefaultTracker *) file->buf);
  414. X        FreeTrackedItem((struct DefaultTracker *) file);
  415. X    }
  416. X    return result;
  417. X}
  418. X
  419. X/*  FUNCTION
  420. X *      OpenARPFile - open a buffered ARP file
  421. X *
  422. X *  SYNOPSIS
  423. X *      #include <MRARPFile.h>
  424. X *
  425. X *      struct MRARPFile *OpenARPFile(name, accessMode, bytes)
  426. X *                                    char *name;
  427. X *                                    LONG accessMode, bytes;
  428. X *
  429. X *  DESCRIPTION
  430. X *      OpenARPFile opens the file <name>, with the given <accessMode>
  431. X *      (MODE_OLDFILE, MODE_NEWFILE only!) for buffered access. The
  432. X *      size of the local buffer is specified by <bytes>.
  433. X *
  434. X *      A zero value for <bytes> is OK and is sometimes appropriate, as
  435. X *      when performing file copy operations, etc. However, if a file
  436. X *      opened with a zero length buffer is then passed to the
  437. X *      FGetsARP function, "spontaneous buffer allocation" will occur.
  438. X *      No biggy, really, just something you should know. The ARP constant,
  439. X *      MaxInputBuf will be used for the buffer size, in this case.
  440. X *
  441. X *      If successful, a pointer to the file tracking structure is 
  442. X *      returned. Otherwise, the return value will be NULL.
  443. X *
  444. X *      OpenARPFile uses full resource tracking for all information
  445. X *      associated with the file.
  446. X *
  447. X */
  448. X
  449. XARPFileHandle *
  450. XOpenARPFile(name, accessMode, bytes)
  451. X    char *name;
  452. X    LONG accessMode, bytes;
  453. X{
  454. X    BPTR                  fh;
  455. X    ARPFileHandle         *theFile = NULL;
  456. X    struct DefaultTracker *lastTracker;
  457. X
  458. X    /* This package does not support READ/WRITE access! */
  459. X
  460. X    if ( (accessMode != MODE_OLDFILE) && (accessMode != MODE_NEWFILE))
  461. X        return NULL;
  462. X
  463. X    theFile = ArpAlloc((LONG) sizeof(ARPFileHandle));
  464. X    if (theFile) {
  465. X        theFile->mode = accessMode;
  466. X        fh = ArpOpen(name, accessMode);
  467. X        lastTracker = LastTracker;
  468. X        if (!fh) {
  469. Xfungu:
  470. X            CloseARPFile(theFile);  /* Don't worry - it's "smart". */
  471. X            theFile = NULL;
  472. X        }
  473. X        theFile->fileTracker = lastTracker;
  474. X        theFile->fh = fh;
  475. X        if ( bytes) {               /* Does user want a buffer? */
  476. X            theFile->buf = ArpAlloc(bytes);
  477. X            if (!theFile->buf) goto fungu;
  478. X            theFile->bufSize = bytes;
  479. X        }
  480. X    }
  481. X    return theFile;  
  482. X}
  483. X
  484. X/*  FUNCTION
  485. X *      SeekARPFile - move to new logical position in file.
  486. X *
  487. X *  SYNOPSIS
  488. X *      #include <MRARPFile.h>
  489. X *
  490. X *      LONG SeekARPFile(file, position, mode)
  491. X *                       ARPFileHandle *file;
  492. X *                       LONG           position;
  493. X *                       LONG           mode;
  494. X *
  495. X *  DESCRIPTION
  496. X *      SeekARPFile attempts to position the <file> to a new logical
  497. X *      position or report it's current position. The <position>
  498. X *      parameter represets a signed offset. The <mode> parameter may
  499. X *      be one of:
  500. X *
  501. X *          OFFSET_BEGINNING (-1) => from beginning of file
  502. X *          OFFSET_CURRENT (0)    => from current position
  503. X *          OFFSET_END (-1)       => from end of file
  504. X *
  505. X *      On output files, the current buffer contents, if any, are
  506. X *      written to disk.
  507. X *
  508. X *      The return value will either be a positive displacement >=0) or
  509. X *      a negated system error code.
  510. X */
  511. XLONG
  512. XSeekARPFile(file, position, mode)
  513. X            ARPFileHandle *file;
  514. X            LONG           position;
  515. X            LONG           mode;
  516. X{
  517. X    LONG    newPosition;
  518. X
  519. X    if (file->mode == MODE_NEWFILE && file->bufLength) {
  520. X        if (FlushARPFileBuffer(file) < 0) {
  521. Xfarboo:
  522. X            return -file->lastError;
  523. X        }
  524. X    }
  525. X    /* Remember our last position. */
  526. X    file->lastPosition = Seek(file->fh, 0L, OFFSET_CURRENT);
  527. X    if ((newPosition = Seek(file->fh, position, mode)) == -1) {
  528. X        file->lastError = IoErr();
  529. X        goto farboo;
  530. X    }
  531. X    return newPosition;
  532. X}  
  533. X
  534. X/*  FUNCTION
  535. X *      WriteARPFile - write data to a buffered ARP file.
  536. X *
  537. X *  SYNOPSIS
  538. X *      #include <MRARPFile.h>
  539. X *
  540. X *      LONG WriteARPFile(ARPFileHandle *file, const char *buffer, LONG length);
  541. X *
  542. X *  DESCRIPTION
  543. X *      WriteARPFile attempts to write <length> bytes from <buffer> to
  544. X *      the buffered ARP file, <file>. The file MUST have been opened
  545. X *      with OpenARPFile for MODE_NEWFILE access.
  546. X *
  547. X *      WriteARPFile will not write to a file if the lastError field is
  548. X *      non-zero, or if the file was opened for input.
  549. X *
  550. X *      If successful, WriteARPFile will return the <length> parameter.
  551. X *      Otherwise, it will return a negated system error code.
  552. X */
  553. XLONG
  554. XWriteARPFile(file, buffer, length)
  555. X    ARPFileHandle   *file;
  556. X    const char      *buffer;
  557. X    LONG            length;
  558. X{
  559. X    LONG    bufferBytes;
  560. X    LONG    bytesLeft = length;
  561. X    LONG    pos = 0;
  562. X    LONG    usedBytes = 0;
  563. X
  564. X    if (file->mode != MODE_NEWFILE)
  565. X        file->lastError = ERROR_WRITE_PROTECTED;
  566. X
  567. X    if (file->lastError) {           /* Catches mode and residual errors. */
  568. Xsumbidge:
  569. X        return -(file->lastError);
  570. X    }
  571. X
  572. X    if ( ! file->buf ) {             /* No buffer? */
  573. X        if (Write(file->fh, buffer, length) != length) {
  574. X            file->lastError = IoErr();
  575. X            goto sumbidge;
  576. X        }
  577. X    }
  578. X    else while (bytesLeft) {
  579. X        /* Need to flush the file's buffer? */
  580. X        if (file->bufPos >= file->bufSize) {
  581. X            if (FlushARPFileBuffer(file) < 0) {
  582. X                goto sumbidge;
  583. X            }
  584. X        }
  585. X        bufferBytes = file->bufSize - file->bufPos;
  586. X        usedBytes = min(bufferBytes, bytesLeft);
  587. X        CopyMem(&buffer[pos], &file->buf[file->bufPos], usedBytes);
  588. X        file->bufLength = (file->bufPos += usedBytes);
  589. X        pos += usedBytes;
  590. X        bytesLeft -= usedBytes;
  591. X    }
  592. X    return length;
  593. X}
  594. X
  595. X/*  Embedded documentation template (cut & paste): */
  596. X
  597. X/*  FUNCTION
  598. X *
  599. X *  SYNOPSIS
  600. X *
  601. X *  DESCRIPTION
  602. X *
  603. X */
  604. END_OF_FILE
  605. if test 17486 -ne `wc -c <'MRARPFile.c'`; then
  606.     echo shar: \"'MRARPFile.c'\" unpacked with wrong size!
  607. fi
  608. # end of 'MRARPFile.c'
  609. fi
  610. echo shar: End of archive 2 \(of 2\).
  611. cp /dev/null ark2isdone
  612. MISSING=""
  613. for I in 1 2 ; do
  614.     if test ! -f ark${I}isdone ; then
  615.     MISSING="${MISSING} ${I}"
  616.     fi
  617. done
  618. if test "${MISSING}" = "" ; then
  619.     echo You have unpacked both archives.
  620.     rm -f ark[1-9]isdone
  621. else
  622.     echo You still need to unpack the following archives:
  623.     echo "        " ${MISSING}
  624. fi
  625. ##  End of shell archive.
  626. exit 0
  627. -- 
  628. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  629. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  630. Post requests for sources, and general discussion to comp.sys.amiga.
  631.